package cn.itsource.user.service.impl;

import cn.itsource.basic.domain.VerificationConstant;
import cn.itsource.basic.util.HttpClientUtils;
import cn.itsource.user.constant.WechatConstant;
import cn.itsource.user.domain.LoginInfo;
import cn.itsource.user.domain.LogininfoDto;
import cn.itsource.user.domain.User;
import cn.itsource.user.domain.Wechat;
import cn.itsource.user.mapper.LoginInfoMapper;
import cn.itsource.user.mapper.UserMapper;
import cn.itsource.user.mapper.WechatMapper;
import cn.itsource.user.service.IWechatService;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import springfox.documentation.spring.web.json.Json;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class WechatServiceImpl implements IWechatService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private WechatMapper mapper;
    @Autowired
    private LoginInfoMapper  infoMapper;
    @Autowired
    private UserMapper userMapper;
    @Override
    public Map<String, Object> handerlcallback(String code) {
        //获取token的url
        String tokenUrl = WechatConstant.TOKEN_URL.replace("APPID", WechatConstant.APPID)
                .replace("SECRET", WechatConstant.SECRET).replace("CODE", code);
        //通过授权码获取token令牌
        String httpGet = HttpClientUtils.httpGet(tokenUrl);
        //把json字符串转为json对象
        JSONObject jsonObject = JSONObject.parseObject(httpGet);
        //获取token
        String access_token = jsonObject.getString("access_token");
        //微信用户唯一标志
        String openid = jsonObject.getString("openid");
        //获取用户资源
        String userinfo_url = WechatConstant.USERINFO_URL.replace("ACCESS_TOKEN", access_token).replace("OPENID", openid);
        //发送请求
        String userinfoJsonstr = HttpClientUtils.httpGet(userinfo_url);
        //转成json对象
        jsonObject = JSONObject.parseObject(userinfoJsonstr);
        HashMap<String, Object> map = new HashMap<>();
        System.out.println(jsonObject);
        //调用方法查询
        Wechat wechat = mapper.loadopenid(openid);

        //判断是否有值  如果为空就证明是第一次扫码
        if (wechat == null) {
            wechat = new Wechat();
            wechat.setOpenid(openid);
            wechat.setSex(jsonObject.getInteger("sex"));
            wechat.setNickname(jsonObject.getString("nickname"));
            wechat.setAddress(jsonObject.getString("country")+" "+jsonObject.getString("province")+" "+jsonObject.getString("city"));
            wechat.setHeadimgurl(jsonObject.getString("headimgurl"));
            mapper.add(wechat);
            map.put("openid", openid);
            return map;
        }else {
            LoginInfo logininfo = wechat.getLoginInfo();
            //如果他为空就证明还是需要绑定  可能扫了一次嘛 微信表保存了  但是没有确认登陆
            if(logininfo== null){
                map.put("openid", openid);
                return  map;

            }

            String token = UUID.randomUUID().toString();
            redisTemplate.opsForValue().set(token, logininfo,30, TimeUnit.MINUTES);
            map.put("token", token);
            map.put("loginUser", logininfo);
            return map;
        }


    }

    @Override
    public Map<String, Object> binder(LogininfoDto logininfoDto) throws Exception {
        //检验数据
        Clickdata(logininfoDto);
        //查看login info表是否有数据
        LoginInfo loginInfo = infoMapper.querybyusernameandtype(logininfoDto.getPhone(), logininfoDto.getType());
        //如果没有  保存数据
        if (loginInfo == null) {
            //创建logininfo
            loginInfo = creatlogininfo(logininfoDto);
            //先保存logininfo
            infoMapper.add(loginInfo);
            //创建user表
            User user = creatuser(loginInfo);
            //再保存user表
            userMapper.add(user);
        }
        //有就直接绑定跳转
        mapper.binder(loginInfo.getId(),logininfoDto.getOpenid());
        System.out.println(logininfoDto.getId());
        HashMap<String, Object> map = new HashMap<>();
        String token = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(token, loginInfo,30, TimeUnit.MINUTES);
        map.put("token", token);
        map.put("loginUser", loginInfo);
        return map;
    }

    private User creatuser(LoginInfo logininfo) {
        User user = new User();
        BeanUtils.copyProperties(logininfo,user);
        user.setState(1);
        user.setLogininfo(logininfo);
        return user;
    }

    private LoginInfo creatlogininfo(LogininfoDto logininfoDto) {
        LoginInfo loginInfo = new LoginInfo();
        loginInfo.setPhone(logininfoDto.getPhone());
        loginInfo.setType(logininfoDto.getType());
        return loginInfo;

    }

    private void Clickdata(LogininfoDto loginInfodto) throws Exception {
        //点换号码
        if(StringUtils.isEmpty(loginInfodto.getPhone())){
            throw  new Exception("电话号码不能为空");
        }
        //判断验证码
        if(loginInfodto.getCode()==null || loginInfodto.getCode().equals("")){
            throw  new Exception("验证码不能为空");
        }
        String valecode = (String) redisTemplate.opsForValue().get(loginInfodto.getPhone() + ":" + VerificationConstant.USER_LOGIN);
        if(StringUtils.isEmpty(valecode)){
            throw  new  Exception("验证码已过期，请重新获取");
        }
        if(loginInfodto.getCode().equals(valecode.split(":")[0])){
            throw  new  Exception("验证码不正确");
        }
    }
}
